feat: add enforceUniqueInstanceID option when scheduling workflows - #116
Open
javier-aliaga wants to merge 1 commit into
Open
feat: add enforceUniqueInstanceID option when scheduling workflows#116javier-aliaga wants to merge 1 commit into
javier-aliaga wants to merge 1 commit into
Conversation
javier-aliaga
force-pushed
the
feat/schedule-if-not-exists
branch
from
July 28, 2026 11:23
b0f6d81 to
4dcf91e
Compare
javier-aliaga
force-pushed
the
feat/schedule-if-not-exists
branch
from
July 28, 2026 11:29
4dcf91e to
2629a47
Compare
javier-aliaga
marked this pull request as ready for review
July 28, 2026 11:32
javier-aliaga
force-pushed
the
feat/schedule-if-not-exists
branch
from
July 29, 2026 09:11
2629a47 to
452c493
Compare
Signed-off-by: Javier Aliaga <javier@diagrid.io>
javier-aliaga
force-pushed
the
feat/schedule-if-not-exists
branch
from
July 29, 2026 09:28
452c493 to
46cf346
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new scheduling option to enforce uniqueness of workflow instance IDs at schedule time, with corresponding gRPC error mapping and new tests to validate behavior.
Changes:
- Add
api.WithEnforceUniqueInstanceID()option to request ALREADY_EXISTS/duplicate-instance behavior on scheduling. - Thread
enforceUniqueInstanceIdthrough the Go client and gRPC executor into backendCreateWorkflowInstance. - Add/adjust tests (orchestration + gRPC) and update backend mocks/signatures to use a request wrapper.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
api/orchestration.go |
Adds public scheduling option WithEnforceUniqueInstanceID() and docs. |
backend/backend.go |
Updates backend interface to accept CreateWorkflowInstanceRequest. |
backend/client.go |
Passes EnforceUniqueInstanceId into backend create call. |
backend/executor.go |
Maps duplicate-instance errors to gRPC codes.AlreadyExists and threads flag through. |
backend/sqlite/sqlite.go |
Updates backend create signature to accept request wrapper. |
backend/postgres/postgres.go |
Updates backend create signature to accept request wrapper. |
backend/client_router_test.go |
Updates fake backend signature for new request wrapper. |
tests/backend_test.go |
Updates backend tests to pass request wrapper. |
tests/mocks/Backend.go |
Updates generated mock to new request type. |
tests/orchestrations_test.go |
Adds orchestration test for enforced-unique instance ID behavior. |
tests/grpc/grpc_test.go |
Adds gRPC test asserting codes.AlreadyExists behavior. |
Files not reviewed (1)
- tests/mocks/Backend.go: Generated file
Suppressed comments (2)
backend/postgres/postgres.go:552
CreateWorkflowInstancenow takes aCreateWorkflowInstanceRequest(which includesenforceUniqueInstanceId), but the current flow doesn’t consult that flag. Without checking it,api.WithEnforceUniqueInstanceID()can’t affect behavior. Consider usingreq.GetEnforceUniqueInstanceId()to decide whether to purge-and-retry when a completed instance already exists (and keep returningapi.ErrDuplicateInstancewhen the existing instance is still running or uniqueness is enforced).
e := req.GetStartEvent()
tx, err := be.db.BeginTx(ctx, pgx.TxOptions{})
if err != nil {
return fmt.Errorf("failed to start transaction: %w", err)
backend/sqlite/sqlite.go:423
CreateWorkflowInstancenow takes aCreateWorkflowInstanceRequest(which includesenforceUniqueInstanceId), but this implementation only usesStartEventand ignores the uniqueness flag. That meansapi.WithEnforceUniqueInstanceID()can’t change behavior, and it also prevents implementing the documented default behavior (restart completed instances when uniqueness is not enforced). Consider usingreq.GetEnforceUniqueInstanceId()to decide whether to purge-and-retry on duplicates for completed instances.
e := req.GetStartEvent()
tx, err := be.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("failed to start transaction: %w", err)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
418
to
+420
|
|
||
| e := req.GetStartEvent() | ||
|
|
Comment on lines
+105
to
+108
| // WithEnforceUniqueInstanceID configures scheduling to fail with an | ||
| // ALREADY_EXISTS error if an instance with the same ID already exists, | ||
| // whether active or completed. Without it, an existing completed instance | ||
| // is restarted. |
Comment on lines
+65
to
+67
| // CreateWorkflowInstance creates a new workflow instance with a request that | ||
| // wraps a ExecutionStarted history event. | ||
| CreateWorkflowInstance(context.Context, *CreateWorkflowInstanceRequest) error |
Comment on lines
547
to
+549
|
|
||
| e := req.GetStartEvent() | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an enforceUniqueInstanceID option when scheduling a workflow. When set, scheduling fails with a gRPC ALREADY_EXISTS error if an instance with the same ID already exists — whether active or completed — so the caller decides how to handle it. Without it, behavior is unchanged (an active duplicate errors, a completed instance is restarted).